package com.nbcio.pm.controller;

import com.nbcio.common.core.domain.R;
import com.nbcio.common.mybatis.core.page.PageQuery;
import com.nbcio.common.mybatis.core.page.TableDataInfo;
import com.nbcio.common.core.validate.AddGroup;
import com.nbcio.common.core.validate.EditGroup;
import com.nbcio.common.log.annotation.Log;
import com.nbcio.common.log.enums.BusinessType;
import com.nbcio.common.web.core.BaseController;
import com.nbcio.pm.domain.bo.PmTeamProjectBo;
import com.nbcio.pm.domain.vo.PmTeamProjectVo;
import com.nbcio.pm.service.IPmTeamProjectService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import cn.dev33.satoken.annotation.SaCheckPermission;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.util.Arrays;
import java.util.List;

/**
 * 团队项目关联Controller
 *
 * @author nbacheng
 */
@Slf4j
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/pm/team-project")
@Tag(name = "团队项目关联", description = "团队项目关联相关接口")
public class PmTeamProjectController extends BaseController {

    private final IPmTeamProjectService pmTeamProjectService;

    /**
     * 查询团队项目关联列表
     */
    @Operation(summary = "查询团队项目关联列表", description = "分页查询团队项目关联列表")
    @SaCheckPermission("pm:team:list")
    @GetMapping("/list")
    public TableDataInfo<PmTeamProjectVo> list(PmTeamProjectBo bo, PageQuery pageQuery) {
        return pmTeamProjectService.queryPageList(bo, pageQuery);
    }

    /**
     * 获取团队项目关联详细信息
     */
    @Operation(summary = "获取团队项目关联详细信息", description = "根据ID获取团队项目关联详细信息")
    @SaCheckPermission("pm:team:query")
    @GetMapping("/{id}")
    public R<PmTeamProjectVo> getInfo(@Parameter(description = "关联ID") @PathVariable Long id) {
        return R.ok(pmTeamProjectService.queryById(id));
    }

    /**
     * 新增团队项目关联
     */
    @Operation(summary = "新增团队项目关联", description = "新增团队项目关联")
    @SaCheckPermission("pm:team:add")
    @Log(title = "团队项目关联", businessType = BusinessType.INSERT)
    @PostMapping
    public R<Void> add(@Validated(AddGroup.class) @RequestBody PmTeamProjectBo bo) {
        return toAjax(pmTeamProjectService.insertByBo(bo));
    }

    /**
     * 修改团队项目关联
     */
    @Operation(summary = "修改团队项目关联", description = "修改团队项目关联")
    @SaCheckPermission("pm:team:edit")
    @Log(title = "团队项目关联", businessType = BusinessType.UPDATE)
    @PutMapping
    public R<Void> edit(@Validated(EditGroup.class) @RequestBody PmTeamProjectBo bo) {
        return toAjax(pmTeamProjectService.updateByBo(bo));
    }

    /**
     * 删除团队项目关联
     */
    @Operation(summary = "删除团队项目关联", description = "根据ID删除团队项目关联")
    @SaCheckPermission("pm:team:remove")
    @Log(title = "团队项目关联", businessType = BusinessType.DELETE)
    @DeleteMapping("/{ids}")
    public R<Void> remove(@Parameter(description = "关联ID列表") @PathVariable Long[] ids) {
        return toAjax(pmTeamProjectService.deleteWithValidByIds(Arrays.asList(ids), true));
    }

    /**
     * 查询团队参与的项目列表
     */
    @Operation(summary = "查询团队参与的项目列表", description = "根据团队ID查询参与的项目列表")
    @SaCheckPermission("pm:team:list")
    @GetMapping("/team/{teamId}/projects")
    public R<List<PmTeamProjectVo>> getTeamProjects(@Parameter(description = "团队ID") @PathVariable Long teamId) {
        List<PmTeamProjectVo> projects = pmTeamProjectService.queryByTeamId(teamId);
        return R.ok(projects);
    }

    /**
     * 查询项目参与的团队列表
     */
    @Operation(summary = "查询项目参与的团队列表", description = "根据项目ID查询参与的团队列表")
    @SaCheckPermission("pm:project:list")
    @GetMapping("/project/{projectId}/teams")
    public R<List<PmTeamProjectVo>> getProjectTeams(@Parameter(description = "项目ID") @PathVariable Long projectId) {
        List<PmTeamProjectVo> teams = pmTeamProjectService.queryByProjectId(projectId);
        return R.ok(teams);
    }

    /**
     * 关联团队到项目
     */
    @Operation(summary = "关联团队到项目", description = "将团队关联到项目，并自动添加团队成员为项目成员")
    @SaCheckPermission("pm:team:edit")
    @Log(title = "团队项目关联", businessType = BusinessType.INSERT)
    @PostMapping("/associate")
    public R<Void> associateTeamToProject(
            @Parameter(description = "团队ID") @RequestParam Long teamId,
            @Parameter(description = "项目ID") @RequestParam Long projectId,
            @Parameter(description = "是否主要团队") @RequestParam(defaultValue = "false") Boolean isPrimary) {
        return toAjax(pmTeamProjectService.associateTeamToProject(teamId, projectId, isPrimary));
    }

    /**
     * 取消团队与项目的关联
     */
    @Operation(summary = "取消团队与项目的关联", description = "取消团队与项目的关联，并移除团队成员从项目成员")
    @SaCheckPermission("pm:team:edit")
    @Log(title = "团队项目关联", businessType = BusinessType.DELETE)
    @PostMapping("/disassociate")
    public R<Void> disassociateTeamFromProject(
            @Parameter(description = "团队ID") @RequestParam Long teamId,
            @Parameter(description = "项目ID") @RequestParam Long projectId) {
        return toAjax(pmTeamProjectService.disassociateTeamFromProject(teamId, projectId));
    }

    /**
     * 批量添加团队成员到项目
     */
    @Operation(summary = "批量添加团队成员到项目", description = "将团队的所有成员添加到项目成员中")
    @SaCheckPermission("pm:team:edit")
    @Log(title = "团队项目关联", businessType = BusinessType.INSERT)
    @PostMapping("/add-members")
    public R<Void> addTeamMembersToProject(
            @Parameter(description = "团队ID") @RequestParam Long teamId,
            @Parameter(description = "项目ID") @RequestParam Long projectId) {
        return toAjax(pmTeamProjectService.addTeamMembersToProject(teamId, projectId));
    }

    /**
     * 从项目移除团队成员
     */
    @Operation(summary = "从项目移除团队成员", description = "将团队的所有成员从项目成员中移除")
    @SaCheckPermission("pm:team:edit")
    @Log(title = "团队项目关联", businessType = BusinessType.DELETE)
    @PostMapping("/remove-members")
    public R<Void> removeTeamMembersFromProject(
            @Parameter(description = "团队ID") @RequestParam Long teamId,
            @Parameter(description = "项目ID") @RequestParam Long projectId) {
        return toAjax(pmTeamProjectService.removeTeamMembersFromProject(teamId, projectId));
    }
}
